<h1 id="PathFinder"><a href="#PathFinder" class="headerlink" title="PathFinder"></a>PathFinder</h1><p> 包含了在游戏中进行寻路的强大方法。这个模块使用原生的高性能 C++ 代码实现，并支持跨越多个房间的自定义寻路成本及路径。</p>
<h2 id="PathFinder.search" class="api-property api-property--method  "><span class="api-property__name">PathFinder.search</span><span class="api-property__args">(origin, goal, [opts])</span>
        <div class="api-property__cpu api-property__cpu--3" title="这种方法的CPU成本很高。"></div>
        </h2>
<pre class="highlight javascript tab-javascript "><code>  <span class="token keyword">let</span> creep <span class="token operator">=</span> Game<span class="token punctuation">.</span>creeps<span class="token punctuation">.</span>John<span class="token punctuation">;</span>

  <span class="token keyword">let</span> goals <span class="token operator">=</span> _<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>creep<span class="token punctuation">.</span>room<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token constant">FIND_SOURCES</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">source</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 我们没办法走到 source 上 -- 将 `range` 设置为 1</span>
    <span class="token comment">// 所以我们将寻路至其旁边</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span> pos<span class="token punctuation">:</span> source<span class="token punctuation">.</span>pos<span class="token punctuation">,</span> range<span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">let</span> ret <span class="token operator">=</span> PathFinder<span class="token punctuation">.</span><span class="token function">search</span><span class="token punctuation">(</span>
    creep<span class="token punctuation">.</span>pos<span class="token punctuation">,</span> goals<span class="token punctuation">,</span>
    <span class="token punctuation">{</span>
      <span class="token comment">// 我们需要把默认的移动成本设置的更高一点</span>
      <span class="token comment">// 这样我们就可以在 roomCallback 里把道路移动成本设置的更低</span>
      plainCost<span class="token punctuation">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
      swampCost<span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">,</span>

      <span class="token function-variable function">roomCallback</span><span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">roomName</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>

        <span class="token keyword">let</span> room <span class="token operator">=</span> Game<span class="token punctuation">.</span>rooms<span class="token punctuation">[</span>roomName<span class="token punctuation">]</span><span class="token punctuation">;</span>
        <span class="token comment">// 在这个示例中，`room` 始终存在</span>
        <span class="token comment">// 但是由于 PathFinder 支持跨多房间检索</span>
        <span class="token comment">// 所以你要更加小心！</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>room<span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span>
        <span class="token keyword">let</span> costs <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">PathFinder<span class="token punctuation">.</span>CostMatrix</span><span class="token punctuation">;</span>

        room<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token constant">FIND_STRUCTURES</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">struct</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
          <span class="token keyword">if</span> <span class="token punctuation">(</span>struct<span class="token punctuation">.</span>structureType <span class="token operator">===</span> <span class="token constant">STRUCTURE_ROAD</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token comment">// 相对于平原，寻路时将更倾向于道路</span>
            costs<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>struct<span class="token punctuation">.</span>pos<span class="token punctuation">.</span>x<span class="token punctuation">,</span> struct<span class="token punctuation">.</span>pos<span class="token punctuation">.</span>y<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>struct<span class="token punctuation">.</span>structureType <span class="token operator">!==</span> <span class="token constant">STRUCTURE_CONTAINER</span> <span class="token operator">&amp;&amp;</span>
                     <span class="token punctuation">(</span>struct<span class="token punctuation">.</span>structureType <span class="token operator">!==</span> <span class="token constant">STRUCTURE_RAMPART</span> <span class="token operator">||</span>
                      <span class="token operator">!</span>struct<span class="token punctuation">.</span>my<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token comment">// 不能穿过无法行走的建筑</span>
            costs<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>struct<span class="token punctuation">.</span>pos<span class="token punctuation">.</span>x<span class="token punctuation">,</span> struct<span class="token punctuation">.</span>pos<span class="token punctuation">.</span>y<span class="token punctuation">,</span> <span class="token number">0xff</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token punctuation">}</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment">// 躲避房间中的 creep</span>
        room<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token constant">FIND_CREEPS</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">creep</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
          costs<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>creep<span class="token punctuation">.</span>pos<span class="token punctuation">.</span>x<span class="token punctuation">,</span> creep<span class="token punctuation">.</span>pos<span class="token punctuation">.</span>y<span class="token punctuation">,</span> <span class="token number">0xff</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">return</span> costs<span class="token punctuation">;</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">let</span> pos <span class="token operator">=</span> ret<span class="token punctuation">.</span>path<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  creep<span class="token punctuation">.</span><span class="token function">move</span><span class="token punctuation">(</span>creep<span class="token punctuation">.</span>pos<span class="token punctuation">.</span><span class="token function">getDirectionTo</span><span class="token punctuation">(</span>pos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>在 <code>origin</code> 和 <code>goal</code> 之间查找最佳路径。</p>
<table><thead><tr><th>parameter</th><th>type</th><th>description</th></tr></thead><tbody>
<tr><td><code>origin</code></td><td><a href="#RoomPosition">RoomPosition</a></td><td><p>起始位置。</p>
</td>
</tr><tr><td><code>goal</code></td><td>object</td><td><p>一个或一组目标。如果提供了多个目标，则返回所有目标中移动成本最低的路径。目标可以是一个 RoomPosition 或者包含下列定义的对象：</p>
<p><em><strong>重要：</strong></em> 请注意，如果您的目标是无法行走的（例如，一个 source），请至少将 <code>range</code> 设置成至少为 1。否则您将浪费很多 CPU 资源来查找一个无法到达的目标。
                    <ul>
                        <li>
                            <div class="api-arg-title">pos</div>
                            <div class="api-arg-type"><a href="#RoomPosition"><code>RoomPosition</code></a></div>
                            <div class="api-arg-desc">目标。</div>
                        </li>
                        <li>
                            <div class="api-arg-title">range</div>
                            <div class="api-arg-type">number</div>
                            <div class="api-arg-desc"><code>pos</code> 周围被当作目的地的范围。默认为 0。</div>
                        </li>
                    </ul></p>
</td>
</tr><tr><td><code>opts (可选)</code></td><td>object</td><td><p>一个包含其他寻路选项的对象。</p>
<ul>
    <li>
        <div class="api-arg-title">roomCallback</div>
        <div class="api-arg-type">function</div>
        <div class="api-arg-desc">该回调可以用来生成某些房间的 <a href="#PathFinder-CostMatrix"><code>CostMatrix</code></a>，并提供给 pathfinder 来增强寻路效果。该回调拥有一个 <code>roomName</code> 参数。在寻路搜索中，每个房间只会被执行一次回调。如果您要在 1 tick 内为单个房间执行多次寻路操作，可以考虑缓存您的 CostMatrix 来提高代码运行效率。请阅读下方的 CostMatrix 文档来了解更多关于 CostMatrix 的信息。如果该回调返回 <code>false</code>，则对应的房间不会被搜索，并且该房间也不会加入到 <code>maxRooms</code>里。</div>
    </li>
    <li>
        <div class="api-arg-title">plainCost</div>
        <div class="api-arg-type">number</div>
        <div class="api-arg-desc">平原上的移动成本，默认为 1。</div>
    </li>
    <li>
        <div class="api-arg-title">swampCost</div>
        <div class="api-arg-type">number</div>
        <div class="api-arg-desc">沼泽上的移动成本，默认为 5。</div>
    </li>
    <li>
        <div class="api-arg-title">flee</div>
        <div class="api-arg-type">boolean</div>
        <div class="api-arg-desc">与其寻找<em>前往</em>目标的道路，不如寻找<em>远离</em>目标的道路。返回远离每个目标 <code>range</code> 的移动成本最低的路径。默认为 false。</div>
    </li>
    <li>
        <div class="api-arg-title">maxOps</div>
        <div class="api-arg-type">number</div>
        <div class="api-arg-desc">寻路所允许的最大消耗。你可以限制用于搜索路径的 CPU 时间，基于 1 op ~ 0.001 CPU 的比例。默认值为 2000。</div>
    </li>
    <li>
        <div class="api-arg-title">maxRooms</div>
        <div class="api-arg-type">number</div>
        <div class="api-arg-desc">寻路所允许的最大房间数。默认值为 16，最大值为 64。</div>
    </li>
    <li>
        <div class="api-arg-title">maxCost</div>
        <div class="api-arg-type">number</div>
        <div class="api-arg-desc">寻路所允许的最大移动成本。如果 pathfinder 发现无论如何都找不到移动成本小于等于 <code>maxCost</code> 的路径时，它将立即停止搜索。默认值为无穷大(Infinity)。</div>
    </li>
    <li>
        <div class="api-arg-title">heuristicWeight</div>
        <div class="api-arg-type">number</div>
        <div class="api-arg-desc">应用于 A* 算法 <code>F = G + weight * H</code> 中的启发式权重(weight)。在使用该选项之前您最好已经了解了 A* 算法的底层实现！默认值为 1.2。</div>
    </li>
</ul></td>
</tr></tbody></table>

<h3 id="返回值"><a href="#返回值" class="headerlink" title="返回值"></a>返回值</h3><p>包含以下属性的对象：</p>
<table>
<thead>
<tr>
<th>属性</th>
<th>介绍</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>path</code></td>
<td>RoomPosition 对象数组。</td>
</tr>
<tr>
<td><code>ops</code></td>
<td>寻路完成时的 operation 总消耗。</td>
</tr>
<tr>
<td><code>cost</code></td>
<td>从 <code>plainCost</code>，<code>swampCost</code> 和任何给定的 CostMatrix 实例推导出的移动总成本。</td>
</tr>
<tr>
<td><code>incomplete</code></td>
<td>如果 pathfinder 找不到完整的路径的话，该值将为 true。注意，<code>path</code> 中依旧会有部分路径，其中的不完整路径代表在当前搜索限制下所能找到的最接近的路径。    </td>
</tr>
</tbody>
</table>
<h2 id="PathFinder.use" class="api-property api-property--method  api-property--deprecated"><span class="api-property__name">PathFinder.use</span><span class="api-property__args">(isEnabled)</span>
        <div class="api-property__cpu api-property__cpu--0" title="该方法的CPU开销很小。"></div>
        </h2>
<div class="api-deprecated"><p>此方法已被弃用，不久将被删除。</p>
</div> 
<pre class="highlight javascript tab-javascript "><code>PathFinder<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
Game<span class="token punctuation">.</span>creeps<span class="token punctuation">.</span>John<span class="token punctuation">.</span><span class="token function">moveTo</span><span class="token punctuation">(</span>Game<span class="token punctuation">.</span>spawns<span class="token punctuation">[</span><span class="token string">'Spawn1'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>指定是否在游戏中使用新的实验性 pathfinder。该方法应在每个 tick 调用。它将影响以下方法的行为：<a href="#Room.findPath"><code>Room.findPath</code></a>, <a href="#RoomPosition.findPathTo"><code>RoomPosition.findPathTo</code></a>, <a href="#RoomPosition.findClosestByPath"><code>RoomPosition.findClosestByPath</code></a>, <a href="#Creep.moveTo"><code>Creep.moveTo</code></a>.</p>
<table><thead><tr><th>parameter</th><th>type</th><th>description</th></tr></thead><tbody>
<tr><td><code>isEnabled</code></td><td>boolean</td><td><p>是否要激活新的 pathfinder。默认值为 <code>true</code>。</p>
</td>
</tr></tbody></table>

